package main

import (
	"fmt"
	"gitcode.com/bangxu/go-wg/utils"
	"github.com/vishvananda/netlink"
	"golang.zx2c4.com/wireguard/wgctrl"
	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
	"log"
	"net"
	"time"
)

/***
golang.zx2c4.com/wireguard/wgctrl"  仅能用于管理和配置已经存在的 tun接口，若tun 接口不存在，则不能创建
https://github.com/andreek/go-netlink-wgctrl/blob/master/main.go   此处有创建网络接口的示例

*/

type Logger struct {
	*log.Logger
}

var (
	ErrorLog *Logger
	InfoLog  *Logger
)

func main() {
	//router := routers.SetupRouter()
	//
	//// 启动HTTP服务器，默认监听在8080端口
	//router.Run()
	utils.InfoLog.Println("Go-WG is starting .........")
	// 启动 Gin 服务器
	go startGinServer()

	// 启动 DNS 服务器
	go startWireGuardServer()

	// 主协程等待，否则程序会立即退出
	select {}

}
func startGinServer() {

	// 这里可以添加代码，保持程序运行，让客户端保持连接状态// ...
}

func startWireGuardServer() {

	// setup wireguard generic link
	la := netlink.NewLinkAttrs()
	la.Name = "wg1"

	addr, _ := netlink.ParseAddr("172.16.20.1/24")
	wgdev := &netlink.GenericLink{LinkAttrs: la, LinkType: "wireguard"}

	err := netlink.LinkAdd(wgdev)
	if err != nil {
		fmt.Printf("could not add %s: %v\n", la.Name, err)
	}
	wg1, _ := netlink.LinkByName(la.Name)
	println(addr)
	//netlink.AddrAdd(wg1, addr)
	//netlink.LinkSetUp(wg1)

	// 用于连接的服务器地址和端口
	//serverAddr := "60.204.226.164"

	// 创建一个新的 WireGuard 控制器
	client, err := wgctrl.New()
	if err != nil {
		log.Fatalf("Failed to create wgctrl client: %v", err)
	}
	defer client.Close()

	iface, err := client.Device("wg1")

	localPrivateKey, err := wgtypes.ParseKey("yAgSFSwkwqPNoV/sq+PVKsETcIotv4S0X1t7kQtUqUg=")

	// 生成新的私钥和公钥
	//localPrivateKey, err := wgtypes.GeneratePrivateKey()
	if err != nil {
		log.Fatalf("Failed to generate private key: %v", err)
	}
	log.Println(localPrivateKey, "    localPrivateKey")
	localPublicKey := localPrivateKey.PublicKey()
	log.Println(localPublicKey, "    localPublicKey")
	//serverPort := 39000
	// 配置服务端接口 wg1

	var markValue int = 42898 // 假设要赋的值是 42
	serverCfg := wgtypes.Config{
		PrivateKey: &localPrivateKey,
		//ListenPort: &serverPort, // 替换为你想要使用的端口号
		FirewallMark: &markValue,
	}

	// 创建WireGuard配置
	peerIP := net.ParseIP("114.67.124.151")
	endPointPort := 39000
	serverPublicKeyStr := "1t4uOydU7rIYQrOSHj3AVCMcxm0S20QbWx+hr2tw92Y="
	serverPublicKey, parseKeyErr := wgtypes.ParseKey(serverPublicKeyStr)
	if parseKeyErr != nil {
		log.Println("parserKeyErr：  ", parseKeyErr)
		return
	}
	// 修改 peerAllowedIPs 的值为 172.16.20.0/24
	peerAllowedIPs := []net.IPNet{{IP: net.ParseIP("172.16.20.0"), Mask: net.CIDRMask(24, 32)}}
	// 创建Peer配置
	peerConfig := wgtypes.PeerConfig{
		PublicKey:  serverPublicKey,
		AllowedIPs: peerAllowedIPs,
		Endpoint:   &net.UDPAddr{IP: peerIP, Port: endPointPort},
	}

	serverCfg.Peers = append(serverCfg.Peers, peerConfig)

	if err := client.ConfigureDevice(iface.Name, serverCfg); err != nil {
		log.Fatalf("Failed to configure wg1 interface: %v", err)
	}

	/**
	这个顺序很重要，竟然是这里出了问题
	*/
	netlink.AddrAdd(wg1, addr)
	netlink.LinkSetUp(wg1)

	time.Sleep(5 * time.Minute) // 保持连接活动，这里示例为10分钟

	// 清除接口配置以关闭连接
	if err := client.ConfigureDevice(iface.Name, wgtypes.Config{}); err != nil {
		log.Fatalf("Failed to clear interface configuration: %v", err)
	}
	err = netlink.LinkDel(wgdev)
	if err != nil {
		fmt.Printf("could not del %s: %v\n", la.Name, err)
	}
}
